package eyer.jmx;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JmxClient {
    private static JmxClient instance = new JmxClient();

    private Logger log = LoggerFactory.getLogger(JmxClient.class);

    private List<JmxConn> connectors = new ArrayList<JmxConn>();

    public static JmxClient getInstance() {
        return instance;
    }

    private JmxClient() {
    }

    public void addConnector(String host, int port, String role) throws JmxClientException {
        try {
            String jmxUrl = "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi";
            JMXServiceURL serviceURL = new JMXServiceURL(jmxUrl);

            Map<String, Object> map = new HashMap<String, Object>();
            String[] credentials = new String[] { "monitorRole", role };
            map.put("jmx.remote.credentials", credentials);

            JMXConnector connector = JMXConnectorFactory.connect(serviceURL, map);
            connectors.add(new JmxConn(host, connector));
        } catch (Exception e) {
            throw new JmxClientException("add-connector-error", e);
        }
    }

    public void disconnect() {
        for (JmxConn conn : connectors) {
            try {
                conn.close();
            } catch (IOException e) {
                log.error("close-connector-error", e);
            }
        }
    }

    private JmxConn getOne(String name) {
        for (JmxConn conn : connectors) {
            if (name.equals(conn.getName()))
                return conn;
        }

        return null;
    }

    public Map<String, Object> getAttrs(String name, String objectName) throws JmxClientException {
        JmxConn conn = getOne(name);
        if (conn == null)
            return null;

        return conn.getAttrs(objectName);
    }
}
